﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;

namespace IDAL
{
    /// <summary>
    /// 仓储接口定义，接口中固定几个数据库操作方法，其他接口都继承自这个接口；
    /// </summary>
    public interface IBaseRepository<TEntity> where TEntity : class, new()
    {
        #region 新增实体
        
        /// <summary>
        /// 新增实体，返回受影响的行
        /// </summary>
        /// <param name="entity"></param>
        int AddEntity(TEntity entity);
        Task<int> AddEntityAsync(TEntity entity);

        #endregion

        #region 修改实体
        /// <summary>
        /// 修改一条数据，返回被修改的实体
        /// </summary>
        /// <param name="entity"></param>
        /// <returns>返回所影响的行</returns>
        int ModifyEntity(TEntity entity);
        Task<int> ModifyEntityAsync(TEntity entity);

        #endregion

        #region 删除实体
        /// <summary>
        /// 删除一个实体对象
        /// </summary>
        /// <param name="entity">必须包含要删除id的对象</param>
        /// <returns></returns>
        bool DeleteEntity(TEntity entity);
        Task<bool> DeleteEntityAsync(TEntity entity);

        /// <summary>
        /// 根据条件批量删除实体对象
        /// </summary>
        /// <param name="whereLambds"></param>
        /// <returns></returns>
        bool DeleteEntitysByLambda(Expression<Func<TEntity, bool>> whereLambda);
        Task<bool> DeleteEntitysByLambdaAsync(Expression<Func<TEntity, bool>> whereLambda);
        #endregion

        #region 查找实体 IQueryable只存贮数据库操作语句，不立即运行，从而可以实现后继修改数据库操作语句  
        /// <summary>
        /// 根据Id查找实体
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        TEntity GetEntityById(int id);
        Task<TEntity> GetEntityByIdAsync(int id);

        /// <summary>
        /// 实现条件查询多个实体并排序
        /// </summary>
        /// <typeparam name="S">按照某个类进行排序</typeparam>
        /// <param name="whereLambda">取得查询的条件</param>
        /// <param name="isAsc">是否升序</param>
        /// <param name="orderByLambd">根据那个字段进行排序</param>
        /// <returns></returns>       
        IQueryable<TEntity> GetEntitysByLambdaAndSort(Expression<Func<TEntity, bool>> whereLambda, Expression<Func<TEntity, object>> orderLambda, bool isAsc);


        /// <summary>
        /// 实现对数据的分页查询，输出总页数及总条数
        /// </summary>
        /// <param name="pageIndex">当前第几页</param> 
        /// <param name="pageSize">一页显示多少条数据</param> 
        /// <param name="rowCount">总条数</param> 
        /// /// <param name="pageCount">总页数</param> 
        /// <param name="whereLambda">获取数据的lambda条件</param> 
        /// <param name="isAsc">是否按升序排</param> 
        /// <param name="OrderByProperty">根据那个字段进行排序</param> 
        /// <returns></returns>  
        //IQueryable<TEntity> GetPagedEntitysByLambdaAndSort(int pageIndex, int pageSize, out int rowCount, out int pageCount, Expression<Func<T, bool>> whereLambda, string orderByProperty, bool isAsc);
        IQueryable<TEntity> GetPagedEntitysByLambdaAndSort(int pageIndex, int pageSize, out int rowCount, out int pageCount, Expression<Func<TEntity, bool>> whereLambda, Expression<Func<TEntity, object>> orderLambda, bool isAsc);

        #endregion

        /// <summary>
        /// 查询记录数
        /// </summary>
        /// <param name="whereLambda">条件表达式</param>
        /// <returns>记录数</returns>
        int Count(Expression<Func<TEntity, bool>> whereLambda);

        /// <summary>
        /// 是否存在
        /// </summary>
        /// <param name="whereLambda">查询表达式</param>
        /// <returns>布尔值</returns>
        bool Exist(Expression<Func<TEntity, bool>> whereLambda);
    }
}
